#include "stdint.h"
#include "stdio.h"
#include "sdkconfig.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/timers.h"

#include "DevicesQueue.h"
#include "DevicesUart.h"
#include "FeedPhy.h"
#include "FeedFrame.h"
#include "FeedPack.h"
#include "FeedApp.h"
#include "mqtt.h"
#include "gatt_svc.h"
#include "esp_log.h"
#include "udp_server.h"

#include "taskNetwork.h"

static const char *TAG = __FILE_NAME__;


/* 通信消息解析任务句柄 */
TaskHandle_t g_TaskNetworkHand = NULL;


/* 解析缓存 */
static uint8_t st_ucDatas[1024];


void vTaskNetwork(void *pvParameters)
{
    QueueType *ptypeQueue;
    int32_t iLength = 0, i;

    while (1)
    {
        /* 等待任务消息 */
        ulTaskNotifyTake(pdTRUE, 100 / portTICK_PERIOD_MS);

        /* 协议解析核心 */
        cFeedKernel();

        /* 读取并解析数据 */
        ptypeQueue = &g_TypeQueueUart0Read;
        while((iLength = iQueueGetLengthSeparetor(ptypeQueue, '\r')) > 0)
        {
            iLength = (iLength > sizeof(st_ucDatas)) ? sizeof(st_ucDatas) : iLength;
            enumQueuePopDatas(ptypeQueue, st_ucDatas, iLength);

            ESP_LOGI(TAG, "%s: %.*s\r\n", ptypeQueue->name, iLength, (char *)st_ucDatas);

            cFeedPackAnalysis(FEED_ADDR_UPPER, st_ucDatas, iLength);
        }

        /* 发送数据 */
        ptypeQueue = &g_TypeQueueUart0Send;
        while((iLength = iQueueGetLengthSeparetor(ptypeQueue, '\r')) > 0)
        {
            iLength = (iLength > sizeof(st_ucDatas)) ? sizeof(st_ucDatas) : iLength;
            enumQueuePopDatas(ptypeQueue, st_ucDatas, iLength);

            ESP_LOGI(TAG, "%s: %.*s\r\n", ptypeQueue->name, iLength, (char *)st_ucDatas);

            vUartSendDatas(&UART0, st_ucDatas, iLength);
        }

        /* 读取并解析数据 */
        ptypeQueue = &g_TypeQueueUart1Read;
        while((iLength = iQueueGetLength(ptypeQueue)) > 0)
        {
            iLength = (iLength > sizeof(st_ucDatas)) ? sizeof(st_ucDatas) : iLength;
            enumQueuePopDatas(ptypeQueue, st_ucDatas, iLength);

            ESP_LOGI(TAG, "%s:", ptypeQueue->name);
            for(i = 0; i <iLength; ++i)
            {
                if(((i % 32) == 0) && (i != 0))
                    printf("\r\n");
                printf("%02X ", st_ucDatas[i]);
            }
            printf("\r\n\n");

            cFeedPackAnalysis(FEED_ADDR_DEVICE, st_ucDatas, iLength);
        }

        /* 发送数据 */
        ptypeQueue = &g_TypeQueueUart1Send;
        while((iLength = iQueueGetLength(ptypeQueue)) > 0)
        {
            iLength = (iLength > sizeof(st_ucDatas)) ? sizeof(st_ucDatas) : iLength;
            enumQueuePopDatas(ptypeQueue, st_ucDatas, iLength);

            ESP_LOGI(TAG, "%s:", ptypeQueue->name);
            for(i = 0; i <iLength; ++i)
            {
                if(((i % 32) == 0) && (i != 0))
                    printf("\r\n");
                printf("%02X ", st_ucDatas[i]);
            }
            printf("\r\n\n");

            vUartSendDatas(&UART1, st_ucDatas, iLength);
        }

        /* 读取并解析数据 */
        ptypeQueue = &g_TypeQueueBleRead;
        while((iLength = iQueueGetLengthSeparetor(ptypeQueue, '\r')) > 0)
        {
            memset(st_ucDatas, 0, sizeof(st_ucDatas));
            iLength = (iLength > sizeof(st_ucDatas)) ? sizeof(st_ucDatas) : iLength;
            enumQueuePopDatas(ptypeQueue, st_ucDatas, iLength);

            ESP_LOGI(TAG, "%s: %.*s\r\n", ptypeQueue->name, iLength, (char *)st_ucDatas);

            cFeedPackAnalysis(FEED_ADDR_BT, st_ucDatas, iLength);
        }

        /* 发送数据 */
        ptypeQueue = &g_TypeQueueBleSend;
        while((iLength = iQueueGetLengthNeed(ptypeQueue, '\r')) > 0)
        {
            iLength = (iLength > (512 - 3)) ? (512 - 3) : iLength;
            enumQueuePopDatas(ptypeQueue, st_ucDatas, iLength);

            ESP_LOGI(TAG, "%s: %.*s\r\n", ptypeQueue->name, iLength, (char *)st_ucDatas);

            ble_datas_send(st_ucDatas, iLength);
        }

        /* 读取并解析数据 */
        ptypeQueue = &g_TypeQueueMqttRead;
        while((iLength = iQueueGetLengthSeparetor(ptypeQueue, '\r')) > 0)
        {
            memset(st_ucDatas, 0, sizeof(st_ucDatas));
            iLength = (iLength > sizeof(st_ucDatas)) ? sizeof(st_ucDatas) : iLength;
            enumQueuePopDatas(ptypeQueue, st_ucDatas, iLength);

            ESP_LOGI(TAG, "%s: %.*s\r\n", ptypeQueue->name, iLength, (char *)st_ucDatas);

            cFeedPackAnalysis(FEED_ADDR_APP, st_ucDatas, iLength);
        }

        /* 发送数据 */
        ptypeQueue = &g_TypeQueueMqttAppSend;
        while((iLength = iQueueGetLengthNeed(ptypeQueue, '\r')) > 0)
        {
            iLength = (iLength > sizeof(st_ucDatas)) ? sizeof(st_ucDatas) : iLength;
            enumQueuePopDatas(ptypeQueue, st_ucDatas, iLength);

            ESP_LOGI(TAG, "%s: %.*s\r\n", ptypeQueue->name, iLength, (char *)st_ucDatas);

            mqtt_datas_send_app(st_ucDatas, iLength);
        }

        /* 发送数据 */
        ptypeQueue = &g_TypeQueueMqttServerSend;
        while((iLength = iQueueGetLengthNeed(ptypeQueue, '\r')) > 0)
        {
            iLength = (iLength > sizeof(st_ucDatas)) ? sizeof(st_ucDatas) : iLength;
            enumQueuePopDatas(ptypeQueue, st_ucDatas, iLength);

            ESP_LOGI(TAG, "%s: %.*s\r\n", ptypeQueue->name, iLength, (char *)st_ucDatas);

            mqtt_datas_send_server(st_ucDatas, iLength);
        }

        /* 读取并解析数据 */
        ptypeQueue = &g_TypeQueueUdpRead;
        while((iLength = iQueueGetLengthSeparetor(ptypeQueue, '\r')) > 0)
        {
            memset(st_ucDatas, 0, sizeof(st_ucDatas));
            iLength = (iLength > sizeof(st_ucDatas)) ? sizeof(st_ucDatas) : iLength;
            enumQueuePopDatas(ptypeQueue, st_ucDatas, iLength);

            ESP_LOGI(TAG, "%s: %.*s\r\n", ptypeQueue->name, iLength, (char *)st_ucDatas);

            cFeedPackAnalysis(FEED_ADDR_UDP, st_ucDatas, iLength);
        }

        /* 发送数据 */
        ptypeQueue = &g_TypeQueueUdpSend;
        while((iLength = iQueueGetLengthNeed(ptypeQueue, '\r')) > 0)
        {
            iLength = (iLength > sizeof(st_ucDatas)) ? sizeof(st_ucDatas) : iLength;
            enumQueuePopDatas(ptypeQueue, st_ucDatas, iLength);

            ESP_LOGI(TAG, "%s: %.*s\r\n", ptypeQueue->name, iLength, (char *)st_ucDatas);

            udp_datas_send(st_ucDatas, iLength);
        }
    }
}
